package model

import (
	"encoding/base64"
	"github.com/jinzhu/gorm"
	"golang.org/x/crypto/scrypt"
	"log"
	"myginblog/utils/errmsg"
)

type User struct {
	gorm.Model
	Username string `gorm:"type:varchar(20);not null" json:"username" validate:"required,min=4,max=12" label:"用户名"`
	Password string `gorm:"type:varchar(20);not null" json:"password" validate:"required,min=6,max=12" label:"密码"`
	Role int	`gorm:"type:int;DEFAULT:2" json:"role" validate:"required,gte=2" label:"角色码"`
}

// 查询用户是否存在
func CheckUser(name string) int{
	var users User

	db.Select("id").Where("username = ?", name).First(&users)

	if users.ID > 0 {
		return errmsg.ERROR_USERNAME_USED
	}

	return errmsg.SUCCSE

}

// 添加用户
func CreateUser(data *User) int{
	// data.Password = ScryptPw(data.Password)
	err := db.Create(&data).Error
	if err != nil {
		return errmsg.ERROR
	}

	return errmsg.SUCCSE
}


// 查询用户列表
func GetUsers(pageSize int, pageNum int) ([]User, int){
	var users []User
	var total int
	err = db.Limit(pageSize).Offset((pageNum-1)*pageSize).Find(&users).Count(&total).Error
	if err != nil  && err != gorm.ErrRecordNotFound{
		return nil, 0
	}
	return users, total
}

// 编辑用户信息，限定在密码以为的字段，密码一般独立在一个单独的接口中完成
func EditUser(id int, data *User) int {
	var user User
	var maps = make(map[string]interface{})
	maps["username"] = data.Username
	maps["role"] = data.Role
	err = db.Model(user).Where("id = ?",id).Updates(maps).Error

	if err != nil {
		return errmsg.ERROR
	}

	return errmsg.SUCCSE
}

// 删除用户
func DeleteUser(id int) int{
	var user User
	err = db.Where("id = ?",id).Delete(&user).Error
	if err != nil {
		return errmsg.ERROR
	}
	return errmsg.SUCCSE
}

// 密码加密
// 钩子函数，在执行参入数据库之前，执行 BeforeSave 函数，Gin 自带
func(u *User)BeforeSave() {
	u.Password = ScryptPw(u.Password)
}

// 密码加密，通过 scrypt 库实现数据加密
func ScryptPw(password string) string{
	const KeyLen = 10
	salt := make([]byte, 8)
	salt = []byte{12, 32, 4 ,5, 42, 232, 12, 23}

	HashPw, err := scrypt.Key([]byte(password), salt, 16384, 8, 1, KeyLen)
	if err != nil {
		log.Fatal(err)
	}

	Fpw := base64.StdEncoding.EncodeToString(HashPw)
	return Fpw
}

// 登录验证
func CheckLogin(username string, password string) int {
	var user User

	db.Where("username = ?", username).First(&user)
	if user.ID == 0 {
		return  errmsg.ERROR_USER_NOT_EXIST
	}

	if ScryptPw(password) != user.Password{
		return  errmsg.ERROR_PASSWORD_WRONG
	}

	if user.Role != 1 {
		return errmsg.ERROR_USER_NO_RIGHT
	}
	return errmsg.SUCCSE
}